﻿#include <cstdio>
#include <iostream>
#include <string.h>
#include "BaseShm.h"
#include "SecKeyShm.h"
using namespace std;


//1.shmget (key_t __key, size_t __size, int __shmflg)
//创建共享内存
//共享内存已经存在，打开共享内存
//可以创建多块共享内存

// 参数1： key_t key : 共享内存在内存中的位置,key大于0整数，  后面介绍一个函数ftork() ， key就是共享内存id
// int shmSize :  创建共享内存的时候，指定共存内存大小
// 如果打开一块共享内存，填写0即可
// int flag：  类似open的flag, 
/**
 * IPC_CREAT: 创建共享内存，  IPC_CREAT| IPC_EXCL： 检测共享内存是否存在
 *                              存在函数返回-1 
 *                              不存在返回0 
 * 
 * IPC_CREAT| 0664 ： 创建贡献内存的时候，需要给共享内存一个权限 
 * 
 * 
 * 返回值： 创建/打开成功 ，得到一个整数， 对应这块内存
 *   -1 ：失败 
 * 
 * 
 * 
 * 2.  m_shmAddr = shmat(m_shmID,  const void *__shmaddr, 0);
 * // 当前进程管理这块共享内存 
 * 参数:
m_shmID:通过这个参数访问共享内存，shmget()函数的返回值shmaddr
__shmaddr :指定共享内存在内核中的位置，写NULL->委托内核区指定
int __shmflg:   SHM_RDONLY  只读 
0 ： 读写
 返回值： 共享内存地址
  失败： 返回-1
 * 

3.shmdt(m_shmAddr);   进程和共享内存分离     m_shmAddr  shmat的返回值
0  成功
-1 失败


4. shmctl(m_shmID, IPC_RMID, NULL): 对共享内存操作函数
 *  m_shmID 参数1： shmget 的返回值  
 *  __cmd： 
 * shmid_ds：
 *  IPC_STAT: 获取共享内存状态
 *  IPC_SET： 设置共享内存状体
 * IPC_RMID： 标记共享内存被销毁， A，B 如果在用，C 无法销毁， A，B  分离以后才销毁   shm_nattch=0的时候


//看上面参数，如果参数1获取，参数2设置，如果cmd =IPC_RMID，第三个参数无用
struct shmid_ds *__buf： 
struct shmid_ds {  //可以获取
  struct ipc_perm shm_perm;            //共享内存权限 ，共存内存创建的时候有权限 
size_t   shm_segsz;                    //共享内存大小，
time t   shm_atime;               //最后一次关联时间 
time_t   shm_dtime;               //最后一次解关联时间 
time_t   shm_ctime;               // 最后一次改变时间 
pid_t    shm_lpid;                // 共享内存是哪个进程创建出来的
shmatt_t  shm_nattch;             // 有多少个进程和该共享内存进行了操作   3个比如  abc 进程
}

  返回值：0 成功
  -1：失败
 *
 */


// 

void readShm();
void writeShm();
int main()
{
	SecKeyShm shm();
	cout << "请输入要进行的操作: " << endl;
	cout << "	1. 写内存, 2. 读内存" << endl;
	int sel = 0;
	cin >> sel;
	switch (sel)
	{
	case 1:
		writeShm();
		break;
	case 2:
		readShm();
		break;
	default:
		break;
	}
	cout << "bye bye!!!" << endl;

	return 0;
}

/// 共享内存实现链表功能 

void writeShm()
{
	NodeSHMInfo info;
	strcpy(info.clientID, "kevin");
	strcpy(info.serverID, "Alice");  //key1 key2如果存在
	strcpy(info.seckey, "我是基督山伯爵...");
	info.seckeyID = 100;
	info.status = 1;
	//在内存按照数组排列， clientid,serverid作为唯一标识，如果存在，覆盖，不存在，添加                
	SecKeyShm shm("/home", 10);    //创建共享内存, 设置大小
	shm.shmInit();                  //清理上面共享内存大小
	shm.shmWrite(&info);             // 共享内存关联进程，写入数据NodeSHMInfo到共享内存


	strcpy(info.clientID, "Bob");
	strcpy(info.serverID, "Jack");
	strcpy(info.seckey, "基督山伯爵就是 - 爱德蒙·唐代斯!!!");
	info.seckeyID = 666;
	info.status = 1;
	shm.shmWrite(&info);
}

void readShm()
{
	char tmp[128];
	strcpy(tmp, "Bob");
	SecKeyShm shm("/home", 10);
	NodeSHMInfo info = shm.shmRead(tmp, "Jack");
	cout << "ClientID: " << info.clientID << endl;
	cout << "ServerID: " << info.serverID << endl;
	cout << "SecKey: " << info.seckey << endl;
	cout << "seckeyID: " << info.seckeyID << endl;
	cout << "status: " << info.status << endl;
	// shm.delShm();
}